package org.pentaho.huaweicloud.obs;

import java.util.regex.Matcher;
import java.util.regex.Pattern;


public final class OBSUtil {

    public static final String KETTLE_USE_HW_DEFAULT_CREDENTIALS = "KETTLE_USE_HW_DEFAULT_CREDENTIALS";

    /** System property name for the HW Endpoint (This is for Minio) */
    public static final String ENDPOINT_SYSTEM_PROPERTY = "hw.endpoint";

    /** System property name for the HW Signature version (This is for Minio) */
    public static final String SIGNATURE_VERSION_SYSTEM_PROPERTY = "hw.endpoint";

    /** System property name for the HW access key ID */
    public static final String ACCESS_KEY_SYSTEM_PROPERTY = "hw.accessKeyId";

    /** System property name for the HW secret key */
    public static final String SECRET_KEY_SYSTEM_PROPERTY = "hw.secretKey";

    /** Environment variable for the HW region */
    public static final String HW_REGION = "HW_REGION";

    /** Environment variable for the specific location of the HW config file */
    public static final String HW_CONFIG_FILE = "HW_CONFIG_FILE";

    /** HW configuration folder */
    public static final String HW_FOLDER = ".hw";

    /** Configuration file name */
    public static final String CONFIG_FILE = "config";

    /** Regex for detecting OBS credentials in URI */
    private static final String URI_HW_CREDENTIALS_REGEX = "(obs[an]?:\\/)?\\/(?<fullkeys>(?<keys>.*:.*)@)?obs[an]?\\/?((?<bucket>[^\\/]+)(?<path>.*))?";

    /** to be used with getKeysFromURI to get the FULL KEYS GROUP **/
    private static final String URI_HW_FULL_KEYS_GROUP = "fullkeys";

    /** to be used with getKeysFromURI to get the KEYS GROUP **/
    private static final String URI_HW_KEYS_GROUP = "keys";

    /** to be used with getKeysFromURI to get the BUCKET GROUP **/
    private static final String URI_HW_BUCKET_GROUP = "bucket";

    /** to be used with getKeysFromURI to get the PATH GROUP **/
    private static final String URI_HW_PATH_GROUP = "path";

    public static boolean hasChanged( String previousValue, String currentValue ) {
        if ( !isEmpty( previousValue ) && isEmpty( currentValue ) ) {
            return true;
        }
        if ( isEmpty( previousValue ) && !isEmpty( currentValue ) ) {
            return true;
        }
        return !isEmpty( previousValue ) && !isEmpty( currentValue ) && !currentValue.equals( previousValue );
    }

    public static boolean isEmpty( String value ) {
        return value == null || value.length() == 0;
    }

    /**
     * Extracts from a OBS URI the credentials including the OBS protocol.
     * Uses URI_HW_CREDENTIALS_REGEX and the group URI_HW_FULL_KEYS_GROUP
     * @param uri string representing the URI
     * @return the full keys extracted from the URI representing "<accesskey>:<secretkey>@obs[]"
     */
    public static String getFullKeysFromURI( String uri ) {
        Matcher match = Pattern.compile( URI_HW_CREDENTIALS_REGEX ).matcher( uri );
        return match.find() ? match.group( URI_HW_FULL_KEYS_GROUP ) : null;
    }

    /**
     * Extracts from a OBS URI the credentials.
     * Uses URI_HW_CREDENTIALS_REGEX and the group URI_HW_KEYS_GROUP
     * @param uri string representing the URI
     * @return the full keys extracted from the URI representing "<accesskey>:<secretkey>"
     */
    public static OBSKeys getKeysFromURI( String uri ) {
        Matcher match = Pattern.compile( URI_HW_CREDENTIALS_REGEX ).matcher( uri );
        return match.find() && match.group( URI_HW_KEYS_GROUP ) != null ? new OBSKeys( match.group( URI_HW_KEYS_GROUP ) ) : null;
    }

    /**
     * OBSKeys object returned by @see getKeysFromURI
     * contains accessKey and secretKey
     */
    public static class OBSKeys {

        private String accessKey;
        private String secretKey;

        private OBSKeys( String keys ) {
            String[] splitKeys = keys.split( ":" );
            accessKey = splitKeys[0];
            secretKey = splitKeys[1];
        }

        public String getAccessKey() {
            return accessKey;
        }

        public String getSecretKey() {
            return secretKey;
        }
    }

    private OBSUtil() { }
}

